﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Koala.Pro.Common
{
    public sealed class ConvertHelper
    {
        public static string ConvertBase(string value, int from, int to)
        {
            if (!isBaseNumber(from))
            {
                throw new ArgumentException("参数from只能是2,8,10,16四个值。");
            }
            if (!isBaseNumber(to))
            {
                throw new ArgumentException("参数to只能是2,8,10,16四个值。");
            }
            string text = Convert.ToString(Convert.ToInt32(value, from), to);
            if (to == 2)
            {
                switch (text.Length)
                {
                    case 7:
                        text = "0" + text;
                        break;
                    case 6:
                        text = "00" + text;
                        break;
                    case 5:
                        text = "000" + text;
                        break;
                    case 4:
                        text = "0000" + text;
                        break;
                    case 3:
                        text = "00000" + text;
                        break;
                }
            }
            return text;
        }

        private static bool isBaseNumber(int baseNumber)
        {
            if (baseNumber == 2 || baseNumber == 8 || baseNumber == 10 || baseNumber == 16)
            {
                return true;
            }
            return false;
        }

        public static byte[] StringToBytes(string text)
        {
            return Encoding.Default.GetBytes(text);
        }

        public static byte[] StringToBytes(string text, Encoding encoding)
        {
            return encoding.GetBytes(text);
        }

        public static string BytesToString(byte[] bytes)
        {
            return Encoding.Default.GetString(bytes);
        }

        public static string BytesToString(byte[] bytes, Encoding encoding)
        {
            return encoding.GetString(bytes);
        }

        public static int BytesToInt32(byte[] data)
        {
            if (data.Length < 4)
            {
                return 0;
            }
            int result = 0;
            if (data.Length >= 4)
            {
                byte[] array = new byte[4];
                Buffer.BlockCopy(data, 0, array, 0, 4);
                result = BitConverter.ToInt32(array, 0);
            }
            return result;
        }

        public static int ToInt32<T>(T data, int defValue)
        {
            if (data == null || Convert.IsDBNull(data))
            {
                return defValue;
            }
            try
            {
                return Convert.ToInt32(data);
            }
            catch
            {
                return defValue;
            }
        }

        public static int ToInt32(string data, int defValue)
        {
            if (string.IsNullOrEmpty(data))
            {
                return defValue;
            }
            int result = 0;
            if (int.TryParse(data, out result))
            {
                return result;
            }
            return defValue;
        }

        public static int ToInt32(object data, int defValue)
        {
            if (data == null || Convert.IsDBNull(data))
            {
                return defValue;
            }
            try
            {
                return Convert.ToInt32(data);
            }
            catch
            {
                return defValue;
            }
        }

        public static bool ToBoolean<T>(T data, bool defValue)
        {
            if (data == null || Convert.IsDBNull(data))
            {
                return defValue;
            }
            try
            {
                return Convert.ToBoolean(data);
            }
            catch
            {
                return defValue;
            }
        }

        public static bool ToBoolean(string data, bool defValue)
        {
            if (string.IsNullOrEmpty(data))
            {
                return defValue;
            }
            bool result = false;
            if (bool.TryParse(data, out result))
            {
                return result;
            }
            return defValue;
        }

        public static bool ToBoolean(object data, bool defValue)
        {
            if (data == null || Convert.IsDBNull(data))
            {
                return defValue;
            }
            try
            {
                return Convert.ToBoolean(data);
            }
            catch
            {
                return defValue;
            }
        }

        public static float ToFloat<T>(T data, float defValue)
        {
            if (data == null || Convert.IsDBNull(data))
            {
                return defValue;
            }
            try
            {
                return Convert.ToSingle(data);
            }
            catch
            {
                return defValue;
            }
        }

        public static float ToFloat(object data, float defValue)
        {
            if (data == null || Convert.IsDBNull(data))
            {
                return defValue;
            }
            try
            {
                return Convert.ToSingle(data);
            }
            catch
            {
                return defValue;
            }
        }

        public static float ToFloat(string data, float defValue)
        {
            if (string.IsNullOrEmpty(data))
            {
                return defValue;
            }
            float result = 0f;
            if (float.TryParse(data, out result))
            {
                return result;
            }
            return defValue;
        }

        public static double ToDouble<T>(T data, double defValue)
        {
            if (data == null || Convert.IsDBNull(data))
            {
                return defValue;
            }
            try
            {
                return Convert.ToDouble(data);
            }
            catch
            {
                return defValue;
            }
        }

        public static double ToDouble<T>(T data, int decimals, double defValue)
        {
            if (data == null || Convert.IsDBNull(data))
            {
                return defValue;
            }
            try
            {
                return Math.Round(Convert.ToDouble(data), decimals);
            }
            catch
            {
                return defValue;
            }
        }

        public static double ToDouble(object data, double defValue)
        {
            if (data == null || Convert.IsDBNull(data))
            {
                return defValue;
            }
            try
            {
                return Convert.ToDouble(data);
            }
            catch
            {
                return defValue;
            }
        }

        public static double ToDouble(string data, double defValue)
        {
            if (string.IsNullOrEmpty(data))
            {
                return defValue;
            }
            double result = 0.0;
            if (double.TryParse(data, out result))
            {
                return result;
            }
            return defValue;
        }

        public static double ToDouble(object data, int decimals, double defValue)
        {
            if (data == null || Convert.IsDBNull(data))
            {
                return defValue;
            }
            try
            {
                return Math.Round(Convert.ToDouble(data), decimals);
            }
            catch
            {
                return defValue;
            }
        }

        public static double ToDouble(string data, int decimals, double defValue)
        {
            if (string.IsNullOrEmpty(data))
            {
                return defValue;
            }
            double result = 0.0;
            if (double.TryParse(data, out result))
            {
                return Math.Round(result, decimals);
            }
            return defValue;
        }

        public static object ConvertTo(object data, Type targetType)
        {
            if (data == null || Convert.IsDBNull(data))
            {
                return null;
            }
            Type type = data.GetType();
            if (targetType == type)
            {
                return data;
            }
            if ((targetType == typeof(Guid) || targetType == typeof(Guid?)) && type == typeof(string))
            {
                if (string.IsNullOrEmpty(data.ToString()))
                {
                    return null;
                }
                return new Guid(data.ToString());
            }
            if (targetType.IsEnum)
            {
                try
                {
                    return Enum.Parse(targetType, data.ToString(), ignoreCase: true);
                }
                catch
                {
                    return Enum.ToObject(targetType, data);
                }
            }
            if (targetType.IsGenericType)
            {
                targetType = targetType.GetGenericArguments()[0];
            }
            return Convert.ChangeType(data, targetType);
        }

        public static T ConvertTo<T>(object data)
        {
            if (data == null || Convert.IsDBNull(data))
            {
                return default(T);
            }
            object obj = ConvertTo(data, typeof(T));
            if (obj == null)
            {
                return default(T);
            }
            return (T)obj;
        }

        public static decimal ToDecimal<T>(T data, decimal defValue)
        {
            if (data == null || Convert.IsDBNull(data))
            {
                return defValue;
            }
            try
            {
                return Convert.ToDecimal(data);
            }
            catch
            {
                return defValue;
            }
        }

        public static decimal ToDecimal(object data, decimal defValue)
        {
            if (data == null || Convert.IsDBNull(data))
            {
                return defValue;
            }
            try
            {
                return Convert.ToDecimal(data);
            }
            catch
            {
                return defValue;
            }
        }

        public static decimal ToDecimal(string data, decimal defValue)
        {
            if (string.IsNullOrEmpty(data))
            {
                return defValue;
            }
            decimal result = default(decimal);
            if (decimal.TryParse(data, out result))
            {
                return result;
            }
            return defValue;
        }

        public static DateTime ToDateTime<T>(T data, DateTime defValue)
        {
            if (data == null || Convert.IsDBNull(data))
            {
                return defValue;
            }
            try
            {
                return Convert.ToDateTime(data);
            }
            catch
            {
                return defValue;
            }
        }

        public static DateTime ToDateTime(object data, DateTime defValue)
        {
            if (data == null || Convert.IsDBNull(data))
            {
                return defValue;
            }
            try
            {
                return Convert.ToDateTime(data);
            }
            catch
            {
                return defValue;
            }
        }

        public static DateTime ToDateTime(string data, DateTime defValue)
        {
            if (string.IsNullOrEmpty(data))
            {
                return defValue;
            }
            DateTime result = DateTime.Now;
            if (DateTime.TryParse(data, out result))
            {
                return result;
            }
            return defValue;
        }

        public static string ConvertToSBC(string input)
        {
            if (string.IsNullOrWhiteSpace(input))
            {
                return "";
            }
            char[] array = input.ToCharArray();
            for (int i = 0; i < array.Length; i++)
            {
                if (array[i] == ' ')
                {
                    array[i] = '\u3000';
                }
                else if (array[i] < '\u007f')
                {
                    array[i] = (char)(array[i] + 65248);
                }
            }
            return new string(array);
        }

        public static string ConvertToDBC(string input)
        {
            if (string.IsNullOrWhiteSpace(input))
            {
                return "";
            }
            char[] array = input.ToCharArray();
            for (int i = 0; i < array.Length; i++)
            {
                if (array[i] == '\u3000')
                {
                    array[i] = ' ';
                }
                else if (array[i] > '\uff00' && array[i] < '｟')
                {
                    array[i] = (char)(array[i] - 65248);
                }
            }
            return new string(array);
        }
    }
}
